import re
from typing import Optional

from pydantic import BaseModel, ConfigDict, Field, validator


class AddressBase(BaseModel):
    """地址基础模型（共享字段）"""
    address_id: int = Field(None,  description="购物车id")
    name: str = Field(..., max_length=50, description="收件人姓名")
    phone: str = Field(..., description="收件人电话")
    province_id: int = Field(..., gt=0, description="省份ID（关联region表）")
    city_id: int = Field(..., gt=0, description="城市ID（关联region表）")
    region_id: int = Field(..., gt=0, description="区/县ID（关联region表）")
    detail: str = Field(..., max_length=200, description="详细地址")
    user_id: int = Field(..., gt=0, description="用户ID")
    province_name: Optional[str] = Field(None, description="省份名称")
    city_name: Optional[str] = Field(None, description="城市名称")
    region_name: Optional[str] = Field(None, description="区/县名称")

    # 手机号格式验证（支持11位手机号）
    @validator('phone')
    def validate_phone(cls, v):
        if not re.match(r'^1[3-9]\d{9}$', v):
            raise ValueError('手机号格式错误（需为11位有效手机号）')
        return v


class AddressCreate(AddressBase):
    """创建地址时使用的模型（无需address_id，由数据库生成）"""
    pass


class AddressUpdate(BaseModel):
    """更新地址时使用的模型（字段均为可选）"""
    name: Optional[str] = Field(None, max_length=50, description="收件人姓名")
    phone: Optional[str] = Field(None, description="收件人电话")
    province_id: Optional[int] = Field(None, gt=0, description="省份ID")
    city_id: Optional[int] = Field(None, gt=0, description="城市ID")
    region_id: Optional[int] = Field(None, gt=0, description="区/县ID")
    detail: Optional[str] = Field(None, max_length=200, description="详细地址")

    # 手机号格式验证（更新时若提供则验证）
    @validator('phone')
    def validate_phone(cls, v):
        if v is None:
            return v
        if not re.match(r'^1[3-9]\d{9}$', v):
            raise ValueError('手机号格式错误（需为11位有效手机号）')
        return v


class AddressInDB(AddressBase):
    """数据库中地址模型（包含主键address_id）"""
    address_id: int = Field(..., gt=0, description="地址ID")

    class Config:
        orm_mode = True  # 支持从SQLAlchemy ORM模型实例化


class AddressResponse(AddressInDB):
    """地址响应模型（可扩展，例如添加省市区名称）"""
    model_config = ConfigDict(
        from_attributes=True,
        extra="ignore",      # 忽略 ORM 多余字段
    )
